home products tech support contact us

 Linux 技術支援    ⇒   基礎篇    進階篇    補腦篇    指令索引    中⇒ENG
版權所有, 引用請註明出處

 檔案擁有者和權限

1.0 檔案擁有者和權限
       擁有者(ownership)
       權限 (permissions)
       目錄的權限
       特殊權限
           Sticky Bit
           SGID (Set Group ID bit)
           SUID (Set User ID Bit)
       chmod 變更檔案的權限
           數字表示法
           符號表示法
       連結檔的權限
       umask 改變預設檔案權限
1.1 檔案屬性
       chattr 變更檔案屬性
       lsattr 顯示檔案屬性


1.0 檔案擁有者和權限
檔案相關指令中有說過:「Linux 下的副檔名只供〝參考〞;例如 Linux 的執行檔不會像 Windows 用〝.exe〞為副檔名」。那 Linux 如何判斷那些檔案是執行檔?為什麼以一般的身份登入,有些目錄進不去?為什麼除了自己建的檔案,其餘的檔案都無法刪除?甚至是許多檔案不讓我讀取?一切都和檔案的〝擁有者〞(ownership) 和〝權限〞(permissions) 有關,講解之前我們來實際體驗一下吧。

例:(以一般的帳號登入測試,不要用〝root〞帳號登入哦,因 Superuser 不受權限規範)
$ cd /root ←進去目錄〝/root〞內玩玩
bash: cd: /root: Permission denied ←許可拒絕
$ cat /etc/shadow ←讀看看帳號密碼的資訊檔〝/etc/shadow〞
cat: /etc/shadow: Permission denied ←許可拒絕
$ cp /etc/shadow ~/ ←複製〝/etc/shadow〞看看
cp: cannot open '/etc/shadow' for reading: Permission denied ←許可拒絕
$ rm -f /bin/ls ←刪掉指令〝/bin/ls〞
rm: cannot remove `/bin/ls': Permission denied ←許可拒絕

擁有者(ownership)
因 Linux 是多人多工(multi-tasking,multi-user)的作業系統,也就是可很多人使用,所以一定要有某種機制來適當的隔離不同登入者檔案的讀、寫、執行和刪除,甚至是進入某個目錄,這種安全機制就是檔案的〝擁有者〞(ownership)和〝權限〞(permission)。

Linux 的檔案的擁有者類別可分〝user 或 owner〞(擁有者)、〝group〞(群組)和〝other〞(其他)各如下:
Linux 登入的時候實際上有兩個身份,一個是登入者(user)另一是伴隨登入者的群組(group),而如有建立檔案,此檔會記錄這兩個身份。

例:
$ echo "hello Wold" > /tmp/myfile ←建立一檔案〝myfile〞
$ ls -l /tmp/myfile ←用 ls -l 列出冗長檔案資訊
-rw-rw-r-- 1 aaa aaa 11 2011-10-10 10:10 myfile ←紅字標記的為 user,綠字標記的為 group

^ back on top ^


權限(permissions)
檔案的權限(permissions),為擁有者(user/group/other)對此檔案是否有〝讀〞、〝寫〞或〝執行〞的能力(Linux 的執行檔可不是根據副檔名,而是執行檔也要有可〝執行〞的權限)。

而檔案的這些權限除了是否可〝執行〞對〝root〞有約束力外,其餘都無效。也就是說如以〝root〞登入會如入無人之境,想幹嘛都可,如刪除檔案或篡改內容。

回顧一下介紹 ls 指令時用 ls -l 列出冗長檔案資訊的例子,如下:

$  ls -l ←列出冗長檔案內容
drw-rw-r-- aaa  aaa  292 2011-09-07  11:44  myfile
 ↑    ↑  ↑         
 permission   user  group        

上例中〝權限〞(permissions)欄位共列出 9 個字元,為了容易識別,刻意以不同的顏色顯示來說明,權限 9 個字元類似〝rwxrwxrwx〞,代表三個不同的擁有者意義如下: 檔案的權限欄位出現的英文字元〝r〞、〝w〞、〝x〞(〝rwx〞順序是固定的)代表對檔案的意義各為 read(讀),write(寫) 和 excute(執行)的權限,而没設定的權限則以〝-〞顯示 。例如〝r--〞只有讀的權限。

下表為權限對檔案的作用:
權限 對檔案的作用
r (讀) 可查看該檔案的內容,如可用 catless 或其他工具來閱讀。
w (寫) 可變更其內容,如可用 vi累加重定向來變更檔案的內容。
x (執行) 如為執行檔則可被執行,但如是 shell script 額外還要有讀的權限才可被執行(因 shell 要讀取該檔)。

例:
$ ls -l /tmp/myfile
-rw-rw-r-- 1 aaa aaa 11 2011-10-10 10:10 myfile

上例 ls -l 輸出權限顯示為〝rw-rw-r--〞紅色字元第一個字元為〝r〞代表擁有者(此為帳號〝aaa〞)對此檔案有〝讀〞的權限,第二個字元為〝w〞 代表擁有者對此檔案有〝寫〞的權限,第三個字元〝-〞,並沒有〝w〞,而是顯示〝-〞代表擁有者對此無執行的權限。
同樣的綠色字體代表〝aaa〞這群組對這檔案也有讀和寫但無執行的權限,而 other(其他)為沒規範在擁有者和群組者皆是,只能讀,不能寫。

接下來我們用不同的帳號來測試一下。

例:
$ echo "hello Wold" > /tmp/myfile ←建立一檔案〝myfile〞
$ ls -l /tmp/myfile ←驗證權限
-rw-rw-r-- 1 aaa aaa 15 2011-09-07 00:46 /tmp/myfile ← 同一 owner/group 可讀寫但 other 只可讀
$ cat /tmp/myfile←讀看看 (測試〝讀〞的權限)
Hello Wold
$ echo 'Hello Linux' >> /tmp/myfile ← 變更〝myfile〞的內容看看(測試〝寫〞的權限)
$ cat /tmp/myfile ←驗證看看
Hello World
Hello Linux
$ su bbb ←暫時變更其他的帳號
Password: ←輸入其帳號密碼
$ cat myfile ←測試〝讀〞的權限
Hello World ←此檔 other 有〝讀〞的權限,故其他人皆可讀取帳號 aaa 所建立的檔案
Hello Linux
$ echo 'Hello Unix' >> /tmp/myfile ←增加〝myfile〞的內容看看
bash: /tmp/myfile: Permission denied ←許可拒絕 (因〝other〞對此檔無〝寫〞的權限)

我們再來看其他的例子。

例:
$ ls -l /etc/shadow ←列出帳號密碼的資訊檔〝/etc/shadow〞的冗長檔案資訊
-r-------- 1 root root 1147 2011-09-07 11:47 /etc/shadow

上例中檔案〝/etc/shadow〞是帳號密碼的影子檔,內容雖都是 ASCII 所編碼的文字檔,但經〝明碼編暗碼〞加密過。由於此檔很重要,有可能會被駭客(Hacker)破解而知每個人帳號的登入密碼,故此檔的擁有者和群組都是〝root〞,而其權限顯示為〝r--------〞表示此檔就算是用〝root〞登入也只能讀不能寫,但不能寫對〝root〞而言是宣示大於實際,因帳號〝root〞特權無限大。

我們再來看看一般的執行檔其擁有者和權限長什麼樣。

例:
$ ls -l /bin/cat
-rwxr-xr-x 1 root root 23360 2007-10-31 11:52 /bin/cat

上例中 cat 這指令其擁有者和群組是〝root〞且可完全讀、寫、和執行,而非〝root〞的擁有者和群組使用此指令的人都算 other 只能讀和執行。

另外有些指令如 cp 會改變目的檔案的擁有者和群組,使之變成操作者所有,其目的是希望複製過來的檔案可完全掌控。

例:(請以一般帳號登入測試)
$ cp /bin/cat ~/ ←複製〝/bin/ls〞到家目錄
$ ls -l /bin/cat  ~/cat ←列出此兩檔比較看看
-rwxr-xr-x 1 root root 23360 2007-10-31 11:52 /bin/cat
-rwxr-xr-x 1 aaa  aaa  23360 2011-10-10 10:10 ./cat ←注意到沒,複製過來的檔案,擁有者和群組都變操作者所有

那要如何保持複製過來的檔案的原汁原味呢?例如備份系統檔時總不能連原擁有者和權限都把它改變了,萬一要復原系統時可就天下大亂。用 cp -acp -p 選項就能保持原檔案的擁有者和權限。

^ back on top ^


目錄的權限
目錄的權限和檔案的權限功能有些不一樣,如下表:
權限 對目錄的作用
r 列出目錄內的檔案或其子目錄(如用 ls 可顯示目錄內的檔案但並非可用 cat 來讀取目錄內的檔案)
w 增減或更名目錄內的檔案(如可對目錄內的檔案操作 rmcpmv 等)
x 進入目錄或執行目錄內的程式(如可 cd 進入目錄)

當然目錄的這些權限對〝root〞都沒有約束力 。

例:
$ ls -l /home ←列出〝/home〞內所有家目權限
drwx------ 28 aaa aaa 4096 4096 2-11-10-11 15:41 aaa
drwx------ 3  bbb bbb 4096 4096 2-11-10-03 19:59 bbb
$ ls /home/bbb ←看別人家裡面有什麼東西?
ls: cannot open directory /home/bbb: Permission denied ←無許可權

上例中顯示每個人的家目錄的 owner 有〝x〞權限故可以自由進入自己的家目錄,且有〝rw〞權限故可列出和增減自己家目錄內的檔案,但其他帳號的使用者為 other 都會被擋在家門口(帳號〝root〞除外)。

特殊權限
權限設定雖可符合大部份的需求,但有灰色地帶;例如某檔案權限為〝rw- --- ---〞,照理說只有擁有者可變更檔案的內容,但 other 卻門戶洞開設為為〝--- --- -wx〞,其目錄的 other 權限有〝x〞(進入目錄的權限)和〝w〞(增減目錄內的檔案) ,這樣別人(other)好像也可進入目錄把不屬於擁有者的檔案刪除或改名。

檔案和目錄的權限互相矛盾要聽誰的?有法律就會有漏洞,有軟體就會有 bug,當然要想辦法防堵,那就是特殊權限的功用。

特殊權限借用權限〝x〞(執行)的位置來設定和顯示,如權限〝x〞的地方顯示〝t〞或〝s〞即表示設了特殊權限。 以下為特殊權限的用途和用法總覽:
特殊權限 檔案/目錄 作用 但書 ls -l 的權限顯示
Sticky bit 目錄 在具有 Sticky bit 的目錄內, 只有該檔的擁有者或〝root〞可以刪除或更名該檔 ohers 也要有〝x 〞權限 --- --- --t
Set Group ID 檔案 只針對執行檔,執行時會暫時變該檔案所屬的群組 group 也要有〝x 〞權限 --- --s ---
目錄 任何放進目錄內的檔案都會變此目錄的群組
Set User ID 檔案 只針對執行檔,執行時會暫時變該檔所屬的擁有者 user 也要有〝x 〞權限 --s --- ---

chmod 變更檔案的權限
指令 chmod (change mode)可改變檔案和目錄的權限特殊權限,只有該檔的擁有者和〝root〞有權去更動其權限。

chmod 可接受〝數字表示法〞(Numberic representation)和〝符號表示法〞(Symbolic representation),這兩種用法的使用者比例旗鼓相當。數字表示法比較簡短,但如非工科的人員可能會對〝十進制轉二進制〞感到頭大,而符號表示法寫起來可能比較冗長。

^ back on top ^


連結檔的權限
如是連結檔,其權限是要依據檔案的本尊還是其分身呢?如是符號連結檔,如用 ls -l 來查詢其權限永遠顯示〝lrwxrwxrwx〞。但其意義可不是任何人都可讀/寫/執行(進入目錄),而是〝完全依本尊的權限〞,如改變符號連結檔的權限,實際是改變原始檔的權限,而符號連結檔永遠不動如山的顯示〝lrwxrwxrwx〞。

如果是硬連結,因硬連結本來就是既是本尊也是分身,故改變本尊或分身的限權,本尊或分身的權限是一起變。

umask 改變預設檔案權限
如用一般身份登入建立一檔案,大部分的 Linux 發行版皆預設檔案的權限為〝rw- rw- r--〞(other 無寫的權限);如為 Superuser 所建立的檔案限制會多一點其檔案權限為〝rw- r-- r--〞(group 和 other 皆無寫的權限)。指令 umask 可變更建立檔案或目錄預設的權限。

例: (此為以一般身份測試,如用〝root〞身份測試,結果會有出入)
$ umask ←如沒任何選項,輸出為顯示建立檔案或目錄時的預設權限
0002

umask 輸出的數字對照下表為建立檔案或目錄的權限。
umask 建立檔案其權限 建立目錄其權限
000
666 (rw- rw- rw-)
777 (rwx rwx rwx)
002
664 (rw- rw- r--)
775 (rwx rwx r-x)
022
644 (rw- r-- r--)
755 (rwx r-x r-x)
027
640 (rw- r-- ---)
750 (rwx r-x ---)
077
600 (rw- --- ---)
700 (rwx --- ---)
277
400 (r-- --- ---)
500 (r-x --- ---)

由表可知 umask= 0002 代表建立檔案其權限為〝rw- rw- r--〞如為目錄其權限為〝rwx rwx r-x〞。

如果要改變建立檔案的預設權限,只要輸入 umask [#][###](〝#〞為數字,參考上表,而第一個〝#〞為特殊權限一般是不更動故保持 0)。

例: (此為以一般身份測試,如用〝root〞身份測試,結果會有出入)
$ umask ←看一下預設權限
0002
$ echo 'umask file1' > umask_0002 ←建立檔案〝umask_0002〞
$ umask 0027 ←改變一下預設權限為〝0027〞(rw- r-- ---)
$ umask ←確認看預設權限己改變了沒
0027 ←變〝0027〞了
$ echo 'umask file2' > umask_0027 ←用 umask=0027 建立檔案〝umask_0027〞
$ ls -l umask_0002 umask_0027 ←列出兩檔案的權限來比較看看
-rw-rw-r-- 1 aaa  aaa  12 2011-10-10 10:10 umask_0002 ←注意比對兩個檔案的權限不一樣了
-rw-r----- 1 aaa  aaa  12 2011-10-10 10:11 umask_0027

一般的應用查表就應夠了,如果想打破砂鍋問到底「為什麼 umask =0002,建立新的檔案其權限為〝rw- rw- r--〞」?可繼續看下去。

umask 是〝user mask〞的縮寫,而〝mask〞計算機工程中譯為〝遮罩〞,遮罩意義為〝經位元運算(bitwise operation)來改變某一 bit〞,其布林邏輯運算式(Boolean operators) 為〝Inital value & ~ umask value〞(initial value 檔案為 666,目錄為 777)或如下的邏輯電路運算。



linux umask

因一般建立的文字檔案沒執行的必要,故權限的數字表示法起始值(initial vale)為〝666〞(rw- rw- rw-)。
上個範例測試中把 umask=002,inital value=666 帶入運算式〝 666 & ~002〞運算結果為〝664〞 (rw-r--r--)。
另一例 umask=027 其 initial value 一樣是 666 帶入運算式〝666 & ~027〞=〝640〞 (rw- r-- ---)。

如建立的是目錄,因要求可進入此一目錄,故起始值為〝777〞(rwx rwx rwx)。
以 umask=002 為例帶入運算式〝777 & ~002〞=〝775〞 (rwx rwx r-x)。

^ back on top ^


1.1 檔案屬性

檔案的權限對帳號〝root〞而言都沒什約束力,因 root 有〝權限豁免權〞。故如不小心操作失誤如下達指令 rm -fr / (根目錄和所有子目錄和檔案都殺無赦),那 Linux 大概要往生了。那有沒有什麼方法來規範 root 呢?那就是〝檔案屬性〞(file attributes),檔案屬性可彌補 root 權力太大的危險。

chattr 變更檔案屬性
chatttr (change attribute)可變更 Linux 檔案的 16 種屬性,約只定義約 8~14 種(不同發行版本支援的屬性數和定義數可能不同)。用法和 chmod 有點類似,以〝+〞表示增加屬性;〝-〞減去屬性;〝=〞為直接設定屬性, 語法如下:
語法:chattr [-otpiton][+-=][mode] file/directroy
指令名稱/功能/命令使用者 選項 功能 mode的種屬性有[aAcdDisSu],意義各為
chattr/
(change attribute)
變更檔案屬性/
Any(主要 for Superuser)
-R 遞回改變檔案的屬性,將目錄下
所有的檔案及子目錄一併異動屬性

〝a〞:用於檔案只能累加,不能刪除。用於目錄只能修改目錄內檔案的內容,但不能增減檔案。且只有〝root〞才可使用
〝A〞:不更新檔案的 atime
〝c〞:存檔時自動壓縮檔案,讀取時自動解壓縮
〝d〞:排除 dump 資料,即執行 dump 指令時會排除此檔
〝D〞如目錄此設定,將緩衝記憶體的資料同步存到硬碟
〝i〞:讓檔案具金剛不壞之身;包括不能刪除,更名,修改內容,變更權限等且只有〝root〞才可使用
〝s〞:毀屍滅跡,當檔案被刪除時,該檔案的 block 會被填 0(讓有心人無法復原該檔)
〝S〞:存檔時不先寫入緩衝記憶體,直接寫進硬碟(效能較差,但比較可防止斷電時,檔案流失)
〝u〞:和〝s〞毀屍滅跡相反,當檔案被剛除時只刪除 inode,以利未來後悔〝可能〞可救回此檔
-V 顯示異動屬性的過程

chattr 的 mode 用法可知許多的屬性都是為了規範〝root〞( Supperuser),如屬性〝a〞主要用於會累加的記錄檔,就算用〝root〞帳號都不能刪除此檔,而 mode 中的屬性〝i〞更是不能動此檔一根寒毛。

刪除某一檔案時,Linux 為了效能,只刪除檔案的 inode 並不會真正把資料(block)清除,如有保密資料,刪除時怕被還原加屬性〝s〞就對了。

實驗:(以〝root〞登入,測試)
# echo '123' > myfile ←建立檔案〝myfile〞
# chattr +a myfile ←設定〝a〞屬性只能累加,但不能刪除
# rm -f myfile ←刪除看看
rm: cannot remove `myfile': Operation not permitted ←許可拒絕
# echo '456' > myfile ←覆寫看看
bash: myfile: Operation not permitted ←許可拒絕
# echo '456' >> myfile ←累加看看
cat myfile ←驗證一下
123
456
# chattr -V -a myfile ←減去〝a〞屬性就可被刪除
chattr 1.40.2 (12-Jul-2007)
Flags of myfile set as ----------------

例:(以〝root〞登入,測試)
# chattr =aAdS file ←設定檔案具有〝a〞,〝A〞,〝d〞,〝S〞屬性
# chattr -V +i -ad file ←將檔案增加〝i〞屬性並減去〝a〞,〝d〞屬性

lsattr 顯示檔案屬性
有時可能會遇到權限沒問題,但就是有某些檔案無法刪除或修改,此時可用 lsattr 來查看屬性是否被 chattr 變動過,lsattrlist attrbute 的縮寫,用來查閱檔案的屬性,用法如下:

語法:lsattr [-otpiton] file/directroy
指令名稱/功能/命令使用者 選項 功能
lsattr/
(list attrbute)顯示檔案屬性/
Any
-a 列出所有檔案和目錄,包括隱藏檔和工作目錄和上層目錄的屬性
-d 只列出目錄屬性
-R 遞回將目錄下的檔案和子目錄列出屬性

例:(以〝root〞登入,測試)
# echo > file
# chattr =aAdS file ←設定檔案具有〝a〞,〝A〞,〝d〞,〝S〞屬性
# lsattr file ←顯示檔案屬性
--S--adA-------- file

例:
# lsattr -a ←列出目錄內所有檔案的屬性(包含工作目錄和其父目錄)
-----a---------- ./. ←工作目錄的屬性
---------------- ./.. ←上層目錄的屬性
-----a---------- ./jun ←目錄內檔案的屬性


^ back on top ^